using System.Reflection;

using log4net.Appender;

using Microsoft.Practices.Unity;

using Ncqrs.Bus;
using Ncqrs.Bus.AzureServiceBus;

using Ncqrs.CommandExecution.AutoMapping;
using Ncqrs.CommandHandling;
using Ncqrs.CommandHandling.Dispatching;
using Ncqrs.Domain;
using Ncqrs.Domain.Bus;
using Ncqrs.EventSourcing.EntityFramework;
using Ncqrs.EventSourcing.Storage;
using Ncqrs.Infrastructure;

using NServiceBus;

using TheKitchen.Commanding.Commands;
using TheKitchen.Events;

namespace TheKitchen.Commanding
{
    public class Bootstrapper
    {
        public void Start()
        {
            SetupDependencies();

//            InitializeNServiceBus();
            InitializeEventBus();
        }

        private static void SetupDependencies()
        {
            var container = ServiceLocator.Current;

            var dispatcher = new InProcessCommandExecutionDispatcher();

            dispatcher.RegisterExecutorForAllCommandsIn(
                Assembly.GetAssembly(typeof (AddNewRecipeCommand)),
                new AutoMappingCommandExecutor());


            

            container.RegisterType<IUniqueIdentifierGenerator, BasicGuidGenerator>(
                new ContainerControlledLifetimeManager());
            container.RegisterInstance<ICommandExecutor>(dispatcher, new ContainerControlledLifetimeManager());
            container.RegisterInstance<IPropertyBagConverter>(new PropertyBagConverter());
            container.RegisterType<IEventStore, EntityFrameworkEventStore>(new ContainerControlledLifetimeManager());
            //container.RegisterType<IEventBus, InProcessEventBus>();
            container.RegisterType<IUnitOfWorkFactory, ThreadBasedUnitOfWorkFactory>();
        }

        //private static void InitializeNServiceBus()
        //{
        //    SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);

        //    IBus bus = Configure.WithWeb()
        //        .Log4Net<FileAppender>(a =>
        //        {
        //            a.AppendToFile = false;
        //            a.File = ".\\nservicebus.log";
        //        })  
        //        .DefaultBuilder()
        //        .XmlSerializer()
        //        .MsmqTransport().IsTransactional(true)
        //        .MsmqSubscriptionStorage()
        //        .UnicastBus()
        //            .LoadMessageHandlers()
        //        .CreateBus()
        //        .Start();

        //    ServiceLocator.Current.RegisterInstance(new DistributedEventBus(bus));
        //}

        private static void InitializeEventBus()
        {
           var inProcesBus = new InProcessEventBus();

            inProcesBus.RegisterHandler<RecipeRated>(new Querying.Core.Denormalizers.RecipesDenormalizer());
            inProcesBus.RegisterHandler<NewRecipeCreated>(new Querying.Core.Denormalizers.RecipesDenormalizer());
            
            ServiceLocator.Current.RegisterInstance<IEventBus>(inProcesBus);
        }

    }
}